<template>
    <div class="verify_content">
        <el-dialog
            v-model="isShowDiag"
            width="420px"
            title="身份验证"
            draggable
            align-center
            closeMsgPop
            @close="closeMsgPop"
        >
            <div class="verify_content_form">
                <div class="verify_content_form_phoneinfo">{{ phoneInfo }}</div>
                <div class="verify_content_form_code">
                    <div class="verify_content_form_code_input">
                        <SvgIcon
                            icon-class="login_msg_code"
                            width="17px"
                            height="21px"
                        />
                        <el-input
                            v-model="captcha"
                            maxlength="6"
                            placeholder="请输入验证码"
                        >
                        </el-input>
                    </div>
                    <span
                        @click="sendMsgBtnClickDbounced"
                        class="verify_content_form_code_btn"
                        :style="[{ color: btnColor }]"
                    >
                        {{ countdownText }}
                    </span>
                </div>
                <el-button
                    class="verify_content_form_footer"
                    @click="checkSms"
                    :loading="isLoading"
                    >验证</el-button
                >
            </div>
        </el-dialog>
    </div>
</template>

<script setup lang="ts">
import { useUserStore } from "@/store";
import { LocationQuery, useRoute } from "vue-router";
import AuthAPI, { type checkSms } from "@/api/auth";
import router from "@/router";

const userStore = useUserStore();
const route = useRoute();

const props = defineProps({
    visible: {
        type: Boolean,
        required: true,
        default: false,
    },
    uid: {
        type: Number,
        required: true,
        default: null,
    },
    tel: {
        type: String,
        required: true,
        default: "",
    },
});
const emits = defineEmits(["update:visible", "onUpdate"]);

let captcha = ref("951123");
let btnColor = ref("green");
let isLoading = ref(false);

let phoneInfo = computed(() => {
    const telephone =
        props.tel.substring(0, 3) + "****" + props.tel.substring(7);
    return `手机号码： ${telephone}`;
});

let countdown = ref<number>(0); // 倒计时
const countdownText = ref<string>("获取验证码"); // 发送验证码信息
let msgTimer: ReturnType<typeof setInterval> | null = null; // 计时器

watch(countdown, (newVal) => {
    if (newVal > 0) {
        btnColor.value = "rgb(210, 210, 210)";
        countdownText.value = `${newVal}秒后重发`;
    } else {
        btnColor.value = "green";
        countdownText.value = "重新发送";
    }
});

// 关闭弹窗
const closeMsgPop = () => (isShowDiag.value = false);

// 弹窗控制器
const isShowDiag = computed({
    get() {
        return props.visible;
    },
    set(val) {
        emits("update:visible", val);
    },
});

//防抖
const sendMsgBtnClickDbounced = useDebounceFn(() => {
    sendMsgBtnClick();
}, 500);

const sendMsgBtnClick = async () => {
    if (countdown.value) return;

    if (msgTimer !== null) {
        clearInterval(msgTimer as NodeJS.Timeout);
    }
    captcha.value = "951123";
    countdown.value = 60;
    await sendMsg();
    msgTimer = setInterval(() => {
        countdown.value -= 1;
        if (countdown.value <= 0) {
            clearInterval(msgTimer as NodeJS.Timeout);
            msgTimer = null;
        }
    }, 1000);
};

// 发送短信
async function sendMsg(): Promise<any> {
    let flag = false;
    let params = {
        tel: props.tel,
        uid: props.uid,
    };

    await AuthAPI.sendSms(params)
        .then(async (res: any) => {
            flag = true;
            ElMessage.success("短信发送成功");
        })
        .catch((err: any) => {
            console.log(err);
        });

    return flag;
}

// 校验验证码
const checkSms = async () => {
    if (!captcha.value.length || captcha.value.length !== 6) {
        ElMessage.warning("请输入六位数验证码!");
        return;
    }

    let params: checkSms = {
        captcha: captcha.value,
        uid: props.uid,
    };
    isLoading.value = true;

    // 校验验证码
    await userStore.checkSms(params).finally(() => {
        // isLoading.value = false;
    });
    // 获取公共信息
    await userStore.getAllCommonUserInfo(params).finally(() => {
        isLoading.value = false;
    });

    // 跳转到登录前的页面;
    const { path, queryParams } = parseRedirect();
    router.push({ path: path, query: queryParams });
};

/**
 * 解析 redirect 字符串 为 path 和  queryParams
 *
 * @returns { path: string, queryParams: Record<string, string> } 解析后的 path 和 queryParams
 */
function parseRedirect(): {
    path: string;
    queryParams: Record<string, string>;
} {
    const query: LocationQuery = route.query;
    const redirect = (query.redirect as string) ?? "/";

    const url = new URL(redirect, window.location.origin);
    const path = url.pathname;
    const queryParams: Record<string, string> = {};

    url.searchParams.forEach((value, key) => {
        queryParams[key] = value;
    });

    return { path, queryParams };
}

onBeforeUpdate(() => {
    if (msgTimer !== null) {
        clearInterval(msgTimer);
        countdown.value = 0;
        captcha.value = "";
    }
});
</script>

<!--element-plus 最外层包裹div deep样式才会生效 -->
<style lang="scss" scoped>
.verify_content {
    :deep(.el-dialog) {
        width: 420px;
        padding: 0;
        .el-dialog__header {
            padding: 0 20px;
            padding-right: 40px;
            .el-dialog__title {
                height: 42px;
                line-height: 42px;
                font-size: 14px;
            }
        }
    }
    &_form {
        display: flex;
        flex-direction: column;
        flex: 1;
        padding: 0 32px;
        &_phoneinfo {
            font-size: 1.5em;
            display: flex;
            align-items: center;
            height: 50px;
        }
        &_code {
            position: relative;
            display: flex;

            &_input {
                padding: 11px 0 11px 50px;
                border: 1px solid #ddd;
                border-radius: 6px;
                position: relative;
                display: flex;
                .icon_login_msg_code {
                    position: absolute;
                    top: 15px;
                    left: 18px;
                }
                .el-input {
                    font-size: 16px;
                    padding-right: 8px;
                }
            }

            &_btn {
                display: flex;
                padding-left: 20px;
                text-align: left;
                align-items: center;
                cursor: pointer;
            }
        }
        &_footer {
            display: flex;
            color: #fff;
            align-items: center;
            text-align: center;
            margin: 25px 0 26px 0;
            height: 38px;
            background: #e93854;
        }
    }
}
</style>
